package com.xbongbong.pro.statistics.helper;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.XbbConstant;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.enums.AggTypeEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.bi.commons.pojo.AggFieldPojo;
import com.xbongbong.pro.dataset.helper.InvokeTableHelper;
import com.xbongbong.pro.domain.entity.ChartEntity;
import com.xbongbong.pro.enums.IntervalTypeEnum;
import com.xbongbong.pro.statistic.enums.AdvancedComputingFirstEnum;
import com.xbongbong.pro.statistic.help.DataSetHelp;
import com.xbongbong.pro.statistic.pojo.ChartFieldAttrPojo;
import com.xbongbong.pro.statistic.result.pojo.FieldAttrPojo;
import com.xbongbong.pro.statistics.help.CommonHelper;
import com.xbongbong.pro.statistics.help.ComputedHelp;
import com.xbongbong.pro.statistics.help.DescribeTableHelper;
import com.xbongbong.pro.statistics.help.StatisticsTableVOHelper;
import com.xbongbong.pro.statistics.service.StarDataService;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * 统计汇总、分组相关
 * @ClassName AggHelper
 * @Author 梁鲁江
 * 创建时间 2022/9/23 11:22
 * 修改时间  2022/9/23 11:22
 **/
@Component
public class AggHelper {
    @Resource
    private DescribeTableHelper describeTableHelper;
    @Resource
    private DataSetHelp dataSetHelp;
    @Resource
    private InvokeTableHelper invokeTableHelper;
    @Resource
    private StarDataService starDataService;
    @Resource
    private CommonHelper commonHelper;
    @Resource
    private StatisticsTableVOHelper statisticsTableVOHelper;
    @Resource
    private ComputedHelp computedHelp;

    private static final Logger logger = LoggerFactory.getLogger(AggHelper.class);
    /**
     * 统计表的处理
     * @param side
     * @param aggFieldMap
     * @param aggFieldsList
     * @param valueAttr
     * @param aggTypeEnum
     * @param attr
     * @param sortMap
     * @param sumTotalFieldsList
     */
    public void addValuesField(String side, Map<String, AggFieldPojo> aggFieldMap, List<String> aggFieldsList, FieldAttrPojo valueAttr, AggTypeEnum aggTypeEnum, String attr, Map<String, String> sortMap, List<String> sumTotalFieldsList,List<String> summaryColumnAlisa) {
        if (EsUtil.setInData(valueAttr.getFieldType())) {
            String aggExtractStr = null;
            //count 设置的时候可能设置为了sum
            if(Objects.equals(AggTypeEnum.COUNT.getCode(),aggTypeEnum.getCode()) || Objects.equals(AggTypeEnum.COUNT.getAlias(),attr)){
                aggExtractStr = AggTypeEnum.COUNT.getAlias() + "()";
                aggTypeEnum = AggTypeEnum.COUNT;
            }else {
                aggExtractStr = aggTypeEnum.getAlias() + "( "  + attr + " ) ";
            }
            //注意序号
            String key;
            Set<String> keySet = aggFieldMap.keySet();
            int i = 1;
            //统计值在一起的顺序
            int index = 0;
            if(keySet.isEmpty()){
                key = aggTypeEnum.getAlias() + "_" +i;
            }else {
                for (String s1 : keySet) {
                    String[] keyArray = s1.split("_");
                    String strType = keyArray[0];
                    String strI = keyArray[1];
                    if(Objects.equals(strType, aggTypeEnum.getAlias())){
                        int j = Integer.parseInt(strI) + 1;
                        if(i<j){
                            i = j;
                        }
                    }
                    index++;
                }
                key = aggTypeEnum.getAlias() + "_" +i;
            }
            aggFieldsList.add(aggExtractStr + " AS " + key);
            // 由于同环比不计算总计（总计不分页，不好算）
            JSONArray advancedComputing = valueAttr.getAdvancedComputing();
            if (AdvancedComputingFirstEnum.noneYearChain(advancedComputing)) {
                sumTotalFieldsList.add(aggExtractStr + " AS " + key);
            }
            summaryColumnAlisa.add(key);
            AggFieldPojo aggFieldPojo = new AggFieldPojo();
            aggFieldPojo.setAggTypeEnum(aggTypeEnum);
            aggFieldPojo.setAttr(attr);
            //多表关联，设置两个不同表的字段时，需要根据表单id进行区分
            aggFieldPojo.setFormId(valueAttr.getFormId());
            aggFieldPojo.setIndex(index);
            aggFieldPojo.setAxis(side);
            //
            aggFieldPojo.setLabelName(valueAttr.getLabelName());
            aggFieldPojo.setFieldType(valueAttr.getFieldType());
            aggFieldPojo.setAdvancedComputing(advancedComputing);
            aggFieldMap.put(key,aggFieldPojo);
            //
            String sortAttrValue = sortMap.get(attr);
            if(StringUtil.isNotEmpty(sortAttrValue) && (Objects.equals(sortAttrValue.trim(), "asc") || Objects.equals(sortAttrValue.trim(), "desc"))){
                String aggStr = key + " " + sortAttrValue;
                sortMap.put(attr, aggStr);
            }
        }else {
            //TODO 
        }
    }

    /**
     * 获取关联字段对应的数据(从结果集里取，不再去查原始表)
     * @param chartEntity
     * @param jsonArray
     * @return
     */
    public Map<String, Map<String, String>> getLinkMap(ChartEntity chartEntity, JSONArray jsonArray) throws XbbException {
        Map<String, Map<String, String>> attrLinkMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (CollectionUtils.isEmpty(jsonArray)) {
            return attrLinkMap;
        }
        List<ChartFieldAttrPojo> linkAttrList = new ArrayList<>();
        describeTableHelper.getStringMapMap(chartEntity, attrLinkMap, linkAttrList);
        if (CollectionUtils.isEmpty(linkAttrList)) {
            return attrLinkMap;
        }
        for (ChartFieldAttrPojo fieldAttrPojo : linkAttrList) {
            String attr = fieldAttrPojo.getAttr();
            String linkedText = fieldAttrPojo.getLinkedText();
            Map<String, String> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (int dataI = 0; dataI < jsonArray.size(); dataI++) {
                JSONObject resultObj = jsonArray.getJSONObject(dataI);
                String ket = resultObj.getString(attr);
                if (ket != null) {
                    String value = FastJsonHelper.getStringOrDefault(resultObj, linkedText, "");
                    map.put(ket,value);
                }
            }
            attrLinkMap.put(attr, map);
        }
        return attrLinkMap;
    }

    /**
     * 设置分组字段
     * @param rowGroupColumnsList  用在colums
     * @param rowGroupFieldsList 用在分组处
     * @param fieldAttrPojo 待解析
     */
    public void setGroupField(List<String> rowGroupColumnsList, List<String> rowGroupFieldsList, FieldAttrPojo fieldAttrPojo,Map<String,FieldAttrPojo> comboFieldMap,ChartEntity chartEntity,Map<String, String> sortFieldMap) {
        String attr = fieldAttrPojo.getAttr();
        Integer fieldType = fieldAttrPojo.getFieldType();
        if(FieldTypeEnum.isDateTimeByFieldType(fieldType)){
            IntervalTypeEnum intervalTypeEnum = IntervalTypeEnum.getByFormatStr(fieldAttrPojo.getDateGroupType());
//                        String s = "UNIX_TIMESTAMP(date_trunc('week', FROM_UNIXTIME(date_1)))" + XbbConstant.AS + attr;
            StringBuilder stringBuilder = new StringBuilder()
                    .append(XbbConstant.UNIX_TIMESTAMP).append(XbbConstant.L_P)
                    .append(XbbConstant.DATE_TRUNC).append(XbbConstant.L_P).append(XbbConstant.SINGLE_QUOTES).append(intervalTypeEnum.getDateTruncFmt()).append(XbbConstant.SINGLE_QUOTES).append(XbbConstant.SQL_COMMA)
                    .append(XbbConstant.FROM_UNIXTIME).append(XbbConstant.L_P).append(attr).append(XbbConstant.R_P)
                    .append(XbbConstant.R_P)
                    .append(XbbConstant.R_P);

            rowGroupFieldsList.add(stringBuilder.toString());
            //分组字段中不能加AS
            stringBuilder.append(XbbConstant.AS).append(attr);
            rowGroupColumnsList.add(stringBuilder.toString());
        }else if (EsHelper.isTeamLogicByFieldType(fieldType, fieldAttrPojo.getBusinessType())){
            //负责作为分组字段   
            int teamIdx = CommonHelper.getTeamIdx(attr, 1);
            String teamKey = XbbConstant.MY_TEAM_MAIN + teamIdx;
            rowGroupColumnsList.add(teamKey);
            rowGroupFieldsList.add(teamKey);
        }else if ((Objects.equals(FieldTypeEnum.ADDRESS.getType(), fieldType) || Objects.equals(FieldTypeEnum.LOCATION.getType(), fieldType))) {
            if (attr.contains(".")) {
                String[] keyArray = attr.split("\\.");
                StringBuilder stringBuilder = new StringBuilder()
                        .append(XbbConstant.GET_JSON_STRING).append(XbbConstant.L_P).append(keyArray[0]).append(XbbConstant.SQL_COMMA).append(XbbConstant.SINGLE_QUOTES).append(XbbConstant.DOLLER).append(XbbConstant.POINT).append(keyArray[1]).append(XbbConstant.SINGLE_QUOTES).append(XbbConstant.R_P);
                rowGroupFieldsList.add(stringBuilder.toString());
                rowGroupColumnsList.add(stringBuilder.append(XbbConstant.AS).append(attr.replaceAll("\\.", "_")).toString());
            }else {
                rowGroupColumnsList.add(attr);
                rowGroupFieldsList.add(attr);
            }
        } else if (Objects.equals(FieldTypeEnum.COMPUTED_FIELD.getType(), fieldType)) {

        }else if(Objects.equals(fieldType, FieldTypeEnum.LINK_BUSINESS_SINGLE.getType())
                || Objects.equals(fieldType, FieldTypeEnum.LINK_RECEIVER.getType())){
            rowGroupFieldsList.add(attr);
            rowGroupColumnsList.add(attr);
            rowGroupColumnsList.add(fieldAttrPojo.getLinkedText());
        }else {
            rowGroupColumnsList.add(attr);
            rowGroupFieldsList.add(attr);
            if(statisticsTableVOHelper.isComboFieldSort(chartEntity,fieldType,sortFieldMap)){
                comboFieldMap.put(attr,fieldAttrPojo);
            }
        }
    }

    /**
     * 处理计算字段
     *
     * @author zyy
     * @date 2022/10/24
     * @version v1.0
     */
    public void addComputedField(ChartEntity chartEntity, String side, Map<String, AggFieldPojo> aggFieldMap, List<String> aggFieldsList, FieldAttrPojo fieldAttrPojo, AggTypeEnum aggTypeEnum, List<String> sumTotalFieldsList,List<String> subQuerySqlOfCountList,List<String> summaryColumnAlisa) throws XbbException {
        //计算字段无需覆盖排序字段的attr
        computedHelp.addComputedField(chartEntity,fieldAttrPojo,aggTypeEnum,side,null,null,aggFieldMap,aggFieldsList, Maps.newHashMap(),sumTotalFieldsList,subQuerySqlOfCountList,summaryColumnAlisa);
    }
}
